package com.chis.netty.simplehttp;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException;
import io.netty.util.CharsetUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;

import static io.netty.handler.codec.http.HttpHeaderNames.*;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * @Description netty的具体实现
 * @Company zwx
 * @author jw
 * @version 2018年7月6日
 */
public class HttpServerHandler extends SimpleChannelInboundHandler<HttpObject> {
	private String result = "";
	/** 日志 */
	private static Logger LOG = LogManager.getLogger(HttpServerHandler.class);
	/** 解码器 */
	private static final HttpDataFactory factory = new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE);
	/** post请求 */
	private HttpPostRequestDecoder decoder;
	/** 不拦截 */
	private static String[] skipApi={
			"/api/statistics/repertoryDetailImport",
			"/api/redire/getUserToken"
	};

	public HttpServerHandler() {
	}

	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) {
		ctx.flush();
	}

	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		if (decoder != null) {
			decoder.cleanFiles();
			ctx.close();
		}
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		ctx.close();
		if (cause instanceof IOException) {
			return;
		}
		cause.printStackTrace();
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
			FullHttpRequest httpRequest = (FullHttpRequest) msg;
			try {
				String path = httpRequest.uri();          //获取路径 uri路径,可以根据 这个判断请求接口
				String body = getBody(httpRequest);     //获取参数
				HttpMethod method = httpRequest.method();//获取请求方法
				System.out.println("接收到:" + method + " 请求:"+path);
				//如果是POST请求
				if (HttpMethod.POST.equals(method)) {
					System.out.println("=============="+body);
				}
				send(ctx, "success", HttpResponseStatus.OK);
			} catch (Exception e) {
				System.out.println("处理请求失败!");
				e.printStackTrace();
			} finally {
				//释放请求
				//httpRequest.release();
			}



	}

	private void send(ChannelHandlerContext ctx, String context, HttpResponseStatus status) {
		FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(context, CharsetUtil.UTF_8));
		response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8");
		ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
	}

	private String getBody(FullHttpRequest request) {
		ByteBuf buf = request.content();
		return buf.toString(CharsetUtil.UTF_8);
	}

	/**
	 * 返回提示
	 * @param ctx ChannelHandlerContext
	 * @param content 返回内容
	 * @throws Exception 异常
	 */
	private void writeResponse(ChannelHandlerContext ctx, String content) throws Exception {
		// 设置response版本，状态，http头，内容等。
		FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(content.getBytes("UTF-8")));
		response.headers().set(CONTENT_TYPE, "application/json;charset=UTF-8");
		// 允许跨域访问
		response.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
		response.headers().set(ACCESS_CONTROL_ALLOW_HEADERS, "Origin, X-Requested-With, Content-Type, Accept,accesscontrolalloworigin,headtoken");
		response.headers().set(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST,OPTIONS");
		response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
		response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());
		response.headers().set(CONNECTION, HttpHeaderValues.KEEP_ALIVE);
		ctx.write(response);
		ctx.flush();
	}
}
